#!/usr/bin/env python3
"""
网格策略运行示例

演示如何配置和运行网格交易策略，支持现货和合约交易
"""

import sys
import os
from datetime import datetime, timedelta
from pathlib import Path

# 添加项目根目录到路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

from xcquant.strategies.grid_strategy import GridStrategy
from xcquant.core.trading_mode import TradingModeManager, TradingConfig, TradingMode
from xcquant.core.unified_core import ConfigManager
from xcquant.core import unified_logger


def run_grid_strategy_simulation():
    """运行网格策略模拟盘示例"""
    
    # 设置日志
    logger = unified_logger.get_logger('grid_strategy_example')
    logger.info("开始运行网格策略模拟盘示例")
    
    try:
        # 1. 创建交易模式配置
        trading_config = TradingConfig(
            mode=TradingMode.SIMULATION,
            exchange='okx',
            initial_balance={'USDT': 10000.0, 'BTC': 0.0},
            risk_limits={
                'max_position_ratio': 0.8,
                'max_drawdown': 0.1,
                'daily_loss_limit': 0.05
            }
        )
        
        # 2. 初始化交易模式管理器
        trading_manager = TradingModeManager()
        if not trading_manager.set_mode(trading_config):
            logger.error("设置交易模式失败")
            return False
        
        # 3. 配置网格策略参数
        strategy_config = {
            # 基础参数
            'symbol': 'BTC-USDT',
            'trade_type': 'spot',  # 现货交易
            
            # 网格参数
            'grid_count': 10,           # 网格数量
            'grid_amount': 100.0,       # 每格金额 (USDT)
            'price_range_percent': 0.1, # 价格范围 10%
            
            # 价格范围 (可选，不设置则自动计算)
            # 'upper_price': 45000.0,
            # 'lower_price': 40000.0,
            
            # 风险控制
            'stop_loss_percent': 0.05,  # 止损 5%
            'take_profit_percent': 0.15, # 止盈 15%
            'max_position_ratio': 0.8,   # 最大仓位比例
            
            # 动态调整
            'enable_dynamic_grid': True,  # 启用动态网格
            'auto_adjust_threshold': 0.05, # 自动调整阈值
            'grid_expansion_ratio': 1.2,   # 网格扩展比例
            'grid_contraction_ratio': 0.8, # 网格收缩比例
            
            # 交易所配置
            'exchange': 'okx'
        }
        
        # 4. 创建网格策略实例
        strategy = GridStrategy(
            config=strategy_config,
            exchange_adapter=trading_manager.get_exchange_adapter(),
            order_manager=trading_manager.get_order_manager(),
            account_manager=trading_manager.get_account_manager(),
            data_manager=trading_manager.get_data_manager()
        )
        
        # 5. 策略已经通过构造函数获得了管理器，无需再次设置
        # strategy.set_order_manager(trading_manager.get_order_manager())
        # strategy.set_account_manager(trading_manager.get_account_manager())
        
        # 6. 验证策略配置
        if not trading_manager.validate_strategy_config(strategy_config):
            logger.error("策略配置验证失败")
            return False
        
        # 7. 初始化策略
        logger.info("初始化网格策略...")
        if not strategy.initialize():
            logger.error("策略初始化失败")
            return False
        
        logger.info("网格策略初始化成功")
        logger.info(f"策略配置: {strategy_config}")
        logger.info(f"交易模式: {trading_manager.get_mode_info()}")
        
        # 8. 模拟运行策略 (实际应用中这里会是实时数据流)
        logger.info("开始模拟运行策略...")
        
        # 模拟价格数据
        import random
        base_price = 42000.0
        
        for i in range(100):  # 模拟100个tick
            # 生成随机价格变动
            price_change = random.uniform(-0.02, 0.02)  # ±2%变动
            current_price = base_price * (1 + price_change)
            
            # 模拟市场数据
            tick_data = {
                'symbol': 'BTC-USDT',
                'price': current_price,
                'timestamp': datetime.now(),
                'volume': random.uniform(0.1, 2.0)
            }
            
            # 调用策略
            try:
                strategy.on_tick('BTC-USDT', tick_data)
            except Exception as e:
                logger.error(f"策略执行错误: {e}")
                continue
            
            # 更新基础价格
            base_price = current_price
            
            # 每10个tick显示一次状态
            if i % 10 == 0:
                account_info = trading_manager.get_account_manager().get_account_info()
                logger.info(f"Tick {i}: 价格={current_price:.2f}, 账户={account_info}")
        
        logger.info("网格策略模拟运行完成")
        return True
        
    except Exception as e:
        logger.error(f"运行网格策略失败: {e}")
        return False
    
    finally:
        # 清理资源
        if 'trading_manager' in locals():
            trading_manager.shutdown()


def run_grid_strategy_backtest():
    """运行网格策略回测示例"""
    
    logger = unified_logger.get_logger('grid_backtest_example')
    logger.info("开始运行网格策略回测示例")
    
    try:
        from xcquant.backtesting.backtest_engine import BacktestEngine
        from xcquant.data.data_manager import DataManager
        
        # 1. 配置回测参数
        backtest_config = {
            'start_date': '2024-01-01',
            'end_date': '2024-01-31',
            'initial_balance': {'USDT': 10000.0},
            'commission_rate': 0.001,  # 0.1% 手续费
            'slippage': 0.0001        # 0.01% 滑点
        }
        
        # 2. 创建回测引擎
        backtest_engine = BacktestEngine(backtest_config)
        
        # 3. 配置网格策略 (合约交易示例)
        strategy_config = {
            'symbol': 'BTC-USDT',
            'trade_type': 'futures',    # 合约交易
            'contract_type': 'swap',    # 永续合约
            'position_side': 'both',    # 双向持仓
            
            # 网格参数
            'grid_count': 20,
            'grid_amount': 50.0,        # 每格50 USDT
            'price_range_percent': 0.15, # 15%价格范围
            
            # 合约特有参数
            'leverage': 3,              # 3倍杠杆
            'hedge_mode': True,         # 对冲模式
            
            # 风险控制
            'stop_loss_percent': 0.08,
            'take_profit_percent': 0.20,
            'max_position_ratio': 0.6,  # 合约降低仓位比例
            
            'exchange': 'okx'
        }
        
        # 4. 创建策略实例
        strategy = GridStrategy(
            config=strategy_config,
            exchange_adapter=None,  # 回测模式不需要真实交易所适配器
            order_manager=None,     # 由回测引擎提供
            account_manager=None,   # 由回测引擎提供
            data_manager=None       # 由回测引擎提供
        )
        backtest_engine.set_strategy(strategy)
        
        # 5. 加载回测数据
        logger.info("加载回测数据...")
        data = backtest_engine.load_data(
            exchange='okx',
            symbol='BTC-USDT',
            interval='1h',
            trade_type='futures'
        )
        
        if data.empty:
            logger.error("回测数据为空，请先下载数据")
            return False
        
        logger.info(f"加载数据成功: {len(data)} 条记录")
        
        # 6. 运行回测
        logger.info("开始回测...")
        results = backtest_engine.run_backtest(data, 'BTC-USDT')
        
        if not results:
            logger.error("回测失败")
            return False
        
        # 7. 显示回测结果
        logger.info("回测完成，生成报告...")
        
        # 生成报告
        report_path = backtest_engine.generate_report('./backtest_results')
        logger.info(f"回测报告已生成: {report_path}")
        
        # 绘制结果图表
        backtest_engine.plot_results('./backtest_results')
        logger.info("回测图表已生成")
        
        # 显示关键指标
        metrics = results.get('metrics', {})
        logger.info("=== 回测结果摘要 ===")
        logger.info(f"总收益率: {metrics.get('total_return', 0):.2%}")
        logger.info(f"年化收益率: {metrics.get('annual_return', 0):.2%}")
        logger.info(f"最大回撤: {metrics.get('max_drawdown', 0):.2%}")
        logger.info(f"夏普比率: {metrics.get('sharpe_ratio', 0):.2f}")
        logger.info(f"交易次数: {metrics.get('total_trades', 0)}")
        logger.info(f"胜率: {metrics.get('win_rate', 0):.2%}")
        
        return True
        
    except Exception as e:
        logger.error(f"回测失败: {e}")
        return False


def main():
    """主函数"""
    print("XCQuant 网格策略示例")
    print("=" * 50)
    print("1. 模拟盘交易示例")
    print("2. 回测示例")
    print("3. 退出")
    
    while True:
        try:
            choice = input("\n请选择运行模式 (1-3): ").strip()
            
            if choice == '1':
                print("\n运行模拟盘交易示例...")
                success = run_grid_strategy_simulation()
                if success:
                    print("✅ 模拟盘交易示例运行成功")
                else:
                    print("❌ 模拟盘交易示例运行失败")
                    
            elif choice == '2':
                print("\n运行回测示例...")
                success = run_grid_strategy_backtest()
                if success:
                    print("✅ 回测示例运行成功")
                else:
                    print("❌ 回测示例运行失败")
                    
            elif choice == '3':
                print("退出程序")
                break
                
            else:
                print("无效选择，请输入 1-3")
                
        except KeyboardInterrupt:
            print("\n\n程序被用户中断")
            break
        except Exception as e:
            print(f"运行错误: {e}")


if __name__ == '__main__':
    main()